package com.supsi.segretaria.server;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 * Mantiene la lista dei messaggi di un'utente cosi riducendo il numero delle chiamate verso DB.
 * Author: Ognjen Palija ognjen@palija.net
 */
public class MessageQueue {
    private List<Message> messages;
    private String queueOwner;
    private DBServer dbServer;

    /**
     * Constructor
     * @param user - username del utente
     */
    public MessageQueue(String user) {
        messages = new ArrayList<Message>();
        queueOwner = user;
        dbServer = DBServer.getInstance();
        messages.addAll( dbServer.getMessages(user) );
    }


    /**
     * Ritorna il numero di tutti i messaggi
     * @return - Il numero di tutti i messaggi
     */
    public int getAllMessagesNumber() {
        return messages.size();
    }

    /**
        @return - Il numero dei messaggi non letti
     */
    public int getUnreadMessagesNumber() {
        return getUnreadMessagesPrv().size();
    }

    /**
        @return lista dei tutti messaggi
     */
    public List<Message> getAllMessages() {
        for(Message msg : messages) {
            if ( msg.isUnread() ) {
                msg.makeMessageRead();
                dbServer.makeMessageRead(msg.getMessageId());
            }
        }
        return new ArrayList<Message>( messages );
    }

    /**
        @return lista dei messaggi non letti
     */
    public List<Message> getUnreadMessages() {
        List<Message> newMessages = new ArrayList<Message>( getUnreadMessagesPrv() );
        for (Message msg : newMessages) {
            msg.makeMessageRead();
            dbServer.makeMessageRead(msg.getMessageId());
        }
        return newMessages;
    }

    /**
        Cancella il messaggio dalla lista e dalla DB. msgNum = 1 significa il messaggio piu' vecchio
     */
    public boolean delMessage(int msgNum) {
        msgNum--;
        if (msgNum >= messages.size() || msgNum < 0 ) {
            return false;
        }
        int msgId = messages.get(msgNum).getMessageId();
        messages.remove(msgNum);
        return dbServer.delMessage(msgId);
    }

    /**
        Cancella tutti i messaggi
     */
    public boolean delAllMessages() {
        messages.clear();
        return dbServer.deleteAllMessages(queueOwner);
    }

    /**
     * Ritorna il messaggio secondo msgNum
     * @param msgNum - indice del messaggio
     * @return Message object
     */
    public Message getMessage(int msgNum) {
        return messages.get(msgNum);
    }

    /**
     * Ricarica la lista dei messaggi leggendoli dalla DB
     */
    public void refreshList() {
        messages.clear();
        messages.addAll(dbServer.getMessages(queueOwner) );
    }

    /**
     * Crea la lista dei messaggi non letti estraendoli dalla lista di tutti messaggi
     * @return
     */
    private List<Message> getUnreadMessagesPrv() {
        List<Message> unreadMessages = new ArrayList<Message>();
        Message msg;
        if (!messages.isEmpty()) {
            Iterator messageIterator = messages.iterator();
            while (messageIterator.hasNext()){
                msg = (Message)messageIterator.next();
                if ( msg.isUnread()) {
                    unreadMessages.add(msg);
                }
            }
        }
        return unreadMessages;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;

        MessageQueue that = (MessageQueue) o;

        if (messages != null ? !messages.equals(that.messages) : that.messages != null) return false;
        if (queueOwner != null ? !queueOwner.equals(that.queueOwner) : that.queueOwner != null) return false;

        return true;
    }

    @Override
    public int hashCode() {
        int result = messages != null ? messages.hashCode() : 0;
        result = 31 * result + (queueOwner != null ? queueOwner.hashCode() : 0);
        return result;
    }
}
